package com.tmt.im.wallet.config.beans;

import com.tmt.im.wallet.service.IgniteService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.util.Assert;

import java.util.Collection;

/**
 * @Description TODO
 * @Author wuyi
 * @Date 2024/8/8 13:03
 * @Version 1.0
 **/
public class MyJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
    private Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter = new MyJwtGrantedAuthoritiesConverter();
    private String principalClaimName = "sub";

    private final IgniteService igniteService;

    public MyJwtAuthenticationConverter(IgniteService igniteService) {
        this.igniteService = igniteService;
    }

    public final AbstractAuthenticationToken convert(Jwt jwt) {
        Collection<GrantedAuthority> authorities = (Collection) this.jwtGrantedAuthoritiesConverter.convert(jwt);
        String principalClaimValue = jwt.getClaimAsString(this.principalClaimName);
        Long id = jwt.getClaim("id");
        //判断令牌的拥有者是否已经登出了系统。
        if (igniteService.isLogout(id, principalClaimValue)) {
            throw new BadCredentialsException("用户已登出系统");
        }
        if (igniteService.isInvalidToken(jwt.getTokenValue())){
            throw new BadCredentialsException("用户令牌已作废");
        }

        return new JwtAuthenticationToken(jwt, authorities, principalClaimValue);
    }

    public void setJwtGrantedAuthoritiesConverter(Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter) {
        Assert.notNull(jwtGrantedAuthoritiesConverter, "jwtGrantedAuthoritiesConverter cannot be null");
        this.jwtGrantedAuthoritiesConverter = jwtGrantedAuthoritiesConverter;
    }

    public void setPrincipalClaimName(String principalClaimName) {
        Assert.hasText(principalClaimName, "principalClaimName cannot be empty");
        this.principalClaimName = principalClaimName;
    }

}
